#pragma once
#include "frontend/lexer.h"
#include "frontend/ast.h"

namespace mspc {

class Parser {

private:
    TokenContainer tokens_;
    std::vector<std::string> errors_;

public:
    Parser(TokenContainer tokens);

    std::unique_ptr<File> parse();

    const std::vector<std::string>& errors() const { return errors_; }
    bool has_errors() const { return !errors_.empty(); }

private:
    // 主解析方法
    std::unique_ptr<File> parse_file();
    std::unique_ptr<ImportStmt> parse_import();
    std::unique_ptr<StructDef> parse_struct();
    std::unique_ptr<MessageDef> parse_message();
    std::unique_ptr<EnumDef> parse_enum();
    std::unique_ptr<FieldDef> parse_field();
    std::unique_ptr<EnumValue> parse_enum_value();
    std::unique_ptr<OptionDef> parse_option();

    // 工具方法
    std::string parse_syntax();
    std::string parse_package();
    std::string parse_type();
    uint32_t parse_number();
    std::string parse_string_literal();
    std::string parse_default_value();
    std::vector<std::unique_ptr<OptionDef>> parse_options();

    // Token处理
    bool check(TokenType type) const;
    bool match(TokenType type);
    Token consume(TokenType type, const std::string& message);
    bool is_valid_identifier(const std::string& ident);

    // 错误处理
    void throw_error(const Token& token, const std::string& message);
    void throw_error(const std::string& message);
};

} // namespace mspc